
#include "hal_common.h"
#include "i2c.h"
#include "msa311.h"
#include "systick.h"
#include <stdio.h>

#define DEBUG_X_Y_Y_DATA  0
#define ENABLE_TAP_DETECT 0
#define ENABLE_ORIENT_DETECT 0
#define ENABLE_ACTIVITE_DETECT 0
#define ENABLE_FREE_FALL_DETECT 1

static bool Msa311_WirteReg(uint8_t reg,uint8_t value)
{
#if I2C_MODE == USER_SW_I2C

    return SwI2c_Device_Write_Data(MSA311_I2CADDR_DEFAULT_8,&reg,1,&value,1);
#elif I2C_MODE == USE_HARD_I2C
    uint8_t tmp[2] = {0};
    tmp[0] = reg;
    tmp[1] = value;
    return BOARD_I2c1_Write(sizeof(tmp),tmp);
#endif

}

static bool Msa311_ReadReg(uint8_t reg,uint8_t *value)
{
#if I2C_MODE == USER_SW_I2C
    return SwI2c_Device_Read_Data(MSA311_I2CADDR_DEFAULT_8,&reg,1,value,1);
#elif I2C_MODE == USE_HARD_I2C
    bool bRet;
    bRet = BOARD_I2c1_Write(1,&reg);
    bRet |= BOARD_I2c1_Read(1,value);
    return bRet;
#endif
}

static bool Msa311_ReadRegs(uint8_t reg,uint8_t *value,uint16_t len)
{
#if I2C_MODE == USER_SW_I2C
    return SwI2c_Device_Read_Data(MSA311_I2CADDR_DEFAULT_8,&reg,1,value,len);
#elif I2C_MODE == USE_HARD_I2C
    bool bRet;
    bRet = BOARD_I2c1_Write(1,&reg);
    bRet |= BOARD_I2c1_Read(len,value);
    return bRet;
#endif
}

static uint8_t Msa311_OffsetConvertToRegister(float g, uint8_t *reg)
{
    *reg = (int8_t)(g / 0.0039f);    
    return 0;                                                                             
}

static uint8_t Msa311_OffsetConvertToData(uint8_t reg, float *g)
{
    *g = (float)(reg) * 0.0039f;    
    return 0;
}

static bool Msa311_Set_Axes_Enable(msa311_axes_state_t state)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_ODR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_Set_Axes_Enable read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_AXES_ENABLE_MSAK) | state);
	bRet = Msa311_WirteReg(MSA311_REG_ODR,w_data);
	if (bRet == false)
	{
		perror("Msa311_Set_Axes_Enable write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_Get_Axes_Enable(msa311_axes_state_t *state)
{
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_ODR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_Set_Axes_Enable read error\n");
		return false;
	}
    *state = (r_data & ~(MSA311_AXES_ENABLE_MSAK));
    
    return bRet;
}

static bool Msa311_SetPowerMode(msa311_powermode_t powerMode)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_POWERMODE,&r_data);
	if (bRet == false)
	{
		perror("msa311_set_power_mode read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_POWER_MODE_MSAK) | powerMode);
	bRet = Msa311_WirteReg(MSA311_REG_POWERMODE,w_data);
	if (bRet == false)
	{
		perror("msa311_set_power_mode write error\n");
		return false;
	}

    return bRet;
}


static bool Msa311_GetPowerMode(msa311_powermode_t *powerMode)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_POWERMODE,&r_data);
	if (bRet == false)
	{
		perror("msa311_set_power_mode read error\n");
		return false;
	}
    *powerMode = (r_data & ~(MSA311_POWER_MODE_MSAK));
    
    return bRet;
}

static bool Msa311_SetDataRate(msa311_dataRate_t dateRate)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_ODR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetDataRate read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_DATA_RATE_MASK) | dateRate);
	bRet = Msa311_WirteReg(MSA311_REG_ODR,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetDataRate write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetDataRate(msa311_dataRate_t *dataRate)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_ODR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetDataRate read error\n");
		return false;
	}
    *dataRate = (r_data & ~(MSA311_DATA_RATE_MASK));
    
    return bRet;
}

static bool Msa311_SetBandWidth(msa301_bandwidth_t bandWidth)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_POWERMODE,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetBandWidth read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_BAND_WIDTH_MASK) | bandWidth);
	bRet = Msa311_WirteReg(MSA311_REG_POWERMODE,w_data);
	if (bRet == false)
	{
		perror("Msa311_GetBandWidth write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetBandWidth(msa301_bandwidth_t *bandWidth)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_POWERMODE,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetBandWidth read error\n");
		return false;
	}
    *bandWidth = (r_data & ~(MSA311_BAND_WIDTH_MASK));
    
    return bRet;
}

static bool Msa311_SetRange(msa311_range_t range)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_RESRANGE,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetRange read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_RANG_MASK) | range);
	bRet = Msa311_WirteReg(MSA311_REG_RESRANGE,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetRange write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetRange(msa311_range_t *range)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_RESRANGE,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetRange read error\n");
		return false;
	}
    *range = (r_data & ~(MSA311_RANG_MASK));
    
    return bRet;
}

static bool Msa311_SetTapQuiteParam(msa311_tapquite_t tapQuite)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_TAPDUR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapQuiteParam read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_TAP_QUITE_MASK) | tapQuite);
	bRet = Msa311_WirteReg(MSA311_REG_TAPDUR,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapQuiteParam write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetTapQuiteParam(msa311_tapquite_t *tapQuite)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_TAPDUR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetRange read error\n");
		return false;
	}
    *tapQuite = (r_data & ~(MSA311_TAP_QUITE_MASK));
    
    return bRet;
}

static bool Msa311_SetTapShockParam(msa311_tapshock_t tapShock)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_TAPDUR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapShockParam read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_TAP_SHOCK_MASK) | tapShock);
	bRet = Msa311_WirteReg(MSA311_REG_TAPDUR,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapShockParam write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetTapShockParam(msa311_tapshock_t *tapShock)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_TAPDUR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetTapShockParam read error\n");
		return false;
	}
    *tapShock = (r_data & ~(MSA311_TAP_SHOCK_MASK));
    
    return bRet;
}

static bool Msa311_SetTapDurationParam(msa311_tapduration_t tapDuration)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_TAPDUR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapDurationParam read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_TAP_DUR_MASK) | tapDuration);
	bRet = Msa311_WirteReg(MSA311_REG_TAPDUR,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapDurationParam write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetTapDurationParam(msa311_tapduration_t *tapDuration)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_TAPDUR,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetTapDurationParam read error\n");
		return false;
	}
    *tapDuration = (r_data & ~(MSA311_TAP_DUR_MASK));
    
    return bRet;
}

static bool Msa311_SetActiveDurationParam(msa311_active_duration_t activeDuration)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_ACTIVE_DURATION,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetActiveDurationParam read error\n");
		return false;
	}
 	w_data = ((r_data & MSA311_ACTIVE_DURATION_MASK) | activeDuration);
	bRet = Msa311_WirteReg(MSA311_REG_ACTIVE_DURATION,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetActiveDurationParam write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetActiveDurationParam(msa311_active_duration_t *activeDuration)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_ACTIVE_DURATION,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetActiveDurationParam read error\n");
		return false;
	}
    *activeDuration = (r_data & ~(MSA311_ACTIVE_DURATION_MASK));
    
    return bRet;
}

static uint8_t Msa311_ThresholdConvertToRegister(float g, uint8_t *reg)
{
    msa311_range_t range;
    Msa311_GetRange(&range);
    switch (range)
    {
    case MSA311_RANGE_2_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.0625f);    
        break;
    case MSA311_RANGE_4_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.125f);    
        break;
    case MSA311_RANGE_8_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.250f);    
        break;
    case MSA311_RANGE_16_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.5f);    
        break;        
    default:
        printf("Msa311_ThresholdConvertToRegister error\r\n");
        break;
    }
    return 0;                                                                             
}

static uint8_t Msa311_ThresholdConvertToData(uint8_t reg, float *g)
{
    msa311_range_t range;
    Msa311_GetRange(&range);
    switch (range)
    {
    case MSA311_RANGE_2_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.0625f;   
        break;
    case MSA311_RANGE_4_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.125f;     
        break;
    case MSA311_RANGE_8_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.250f;     
        break;
    case MSA311_RANGE_16_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.500f;    
        break;        
    default:
        printf("Msa311_ThresholdConvertToData error\r\n");
        break;
    }
    
    *g = (float)(reg) * 0.0039f;    
    return 0;
}

static bool Msa311_SetTapThresholdParam(uint8_t threshold)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

 	w_data = threshold;
	bRet = Msa311_WirteReg(MSA311_REG_TAPTH,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapThresholdParam write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetTapThresholdParam(uint8_t *threshold)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_TAPTH,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetTapThresholdParam read error\n");
		return false;
	}
    *threshold = r_data;
    
    return bRet;
}

static uint8_t Msa311_ActiveThresholdConvertToRegister(float g, uint8_t *reg)
{
    msa311_range_t range;
    Msa311_GetRange(&range);
    switch (range)
    {
    case MSA311_RANGE_2_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.00391f);    
        break;
    case MSA311_RANGE_4_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.00781f);    
        break;
    case MSA311_RANGE_8_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.015625f);    
        break;
    case MSA311_RANGE_16_G/* constant-expression */:
        /* code */
        *reg = (int8_t)(g / 0.03125f);    
        break;        
    default:
        printf("Msa311_ActiveThresholdConvertToRegister error\r\n");
        break;
    }
    return 0;                                                                             
}

static uint8_t Msa311_ActiveThresholdConvertToData(uint8_t reg, float *g)
{
    msa311_range_t range;
    Msa311_GetRange(&range);
    switch (range)
    {
    case MSA311_RANGE_2_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.00391f;   
        break;
    case MSA311_RANGE_4_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.00781f;     
        break;
    case MSA311_RANGE_8_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.015625f;     
        break;
    case MSA311_RANGE_16_G/* constant-expression */:
        /* code */
        *g = (float)(reg) * 0.03125f;    
        break;        
    default:
        printf("Msa311_ActiveThresholdConvertToData error\r\n");
        break;
    }
    
    *g = (float)(reg) * 0.0039f;    
    return 0;
}

static bool Msa311_SetActiveThresholdParam(uint8_t threshold)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

 	w_data = threshold;
	bRet = Msa311_WirteReg(MSA311_REG_ACTIVE_THRESHOLD,w_data);
	if (bRet == false)
	{
		perror("Msa311_SetActiveThresholdParam write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetActiveThresholdParam(uint8_t *threshold)
{    
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_ACTIVE_THRESHOLD,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetActiveThresholdParam read error\n");
		return false;
	}
    *threshold = r_data;
    
    return bRet;
}

static bool Msa311_SetInterruptMap0(msa311_interrupt_map0_t type, msa311_bool_t enable)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_INTMAP0,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterruptMap0 read error\n");
		return false;
	}
 	r_data &= ~(1 << type);                                                                   /* clear type */
    r_data |= enable << type; 

	bRet = Msa311_WirteReg(MSA311_REG_INTMAP0,r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterruptMap0 write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetInterruptMap0(msa311_interrupt_map0_t type, msa311_bool_t *enable)
{
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_INTMAP0,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterruptMap0 read error\n");
		return false;
	}
    r_data &= (1 << type);                                                                    /* clear config */
    *enable = (msa311_bool_t)(r_data >> type);   

    return 0;
}

static bool Msa311_SetInterrupt0Enable(msa311_interrupt_sw0_t type, msa311_bool_t enable)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_INTSET0,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterrupt0Enable read error\n");
		return false;
	}
 	r_data &= ~(1 << type);                                                                   /* clear type */
    r_data |= enable << type; 

	bRet = Msa311_WirteReg(MSA311_REG_INTSET0,r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterrupt0Enable write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetInterrupt0Enable(msa311_interrupt_sw0_t type, msa311_bool_t *enable)
{
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_INTSET0,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetInterrupt0Enable read error\n");
		return false;
	}
    r_data &= (1 << type);                                                                    /* clear config */
    *enable = (msa311_bool_t)(r_data >> type);   

    return 0;
}

static bool Msa311_SetInterrupt1Enable(msa311_interrupt_sw1_t type, msa311_bool_t enable)
{
    uint8_t r_data;
	uint8_t w_data;
	bool bRet = 0;

	bRet = Msa311_ReadReg(MSA311_REG_INTSET1,&r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterrupt1Enable read error\n");
		return false;
	}
 	r_data &= ~(1 << type);                                                                   /* clear type */
    r_data |= enable << type; 

	bRet = Msa311_WirteReg(MSA311_REG_INTSET1,r_data);
	if (bRet == false)
	{
		perror("Msa311_SetInterrupt1Enable write error\n");
		return false;
	}

    return bRet;
}

static bool Msa311_GetInterrupt1Enable(msa311_interrupt_sw1_t type, msa311_bool_t *enable)
{
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_INTMAP1,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetInterrupt1Enable read error\n");
		return false;
	}
    r_data &= (1 << type);                                                                    /* clear config */
    *enable = (msa311_bool_t)(r_data >> type);   

    return 0;
}

static bool Msa311_GetInterruptState(msa311_int_state_t state, msa311_bool_t *enable)
{
    uint8_t r_data;
	bool bRet = 0;

    bRet = Msa311_ReadReg(MSA311_REG_MOTIONINT,&r_data);
	if (bRet == false)
	{
		perror("Msa311_GetInterrupt1Enable read error\n");
		return false;
	}
    r_data &= (1 << state);                                                                    /* clear config */
    *enable = (msa311_bool_t)(r_data >> state);   

    return 0;
}

static bool Msa311_GetPardId(uint8_t *id)
{
    return Msa311_ReadReg(MSA311_REG_PARTID,id);
}

static bool Msa311_SetOffset(uint8_t x, uint8_t y, uint8_t z) 
{
    bool bRet ;
    bRet = Msa311_WirteReg(MSA311_REG_OFFSET_X,x);
    bRet |=Msa311_WirteReg(MSA311_REG_OFFSET_X,y);
    bRet |=Msa311_WirteReg(MSA311_REG_OFFSET_X,z);

    return bRet;
}

static bool Msa311_GetOffset(uint8_t *x, uint8_t *y, uint8_t *z) 
{
    bool bRet ;
    bRet = Msa311_ReadReg(MSA311_REG_OFFSET_X,x);
    bRet |= Msa311_ReadReg(MSA311_REG_OFFSET_X,y);
    bRet |= Msa311_ReadReg(MSA311_REG_OFFSET_X,z);

    return bRet;
}

static bool Msa311_SetFreeFallDuration(uint8_t duration)
{
    bool bRet;
    bRet = Msa311_WirteReg(MSA311_REG_FREE_FALL_DURATION,duration);
	if (bRet == false)
	{
		perror("Msa311_SetFreeFallDuration write error\n");
		return false;
	}

    return true;
}

static bool Msa311_SetFreeFallThreshole(uint8_t threshole)
{
    bool bRet;
    bRet = Msa311_WirteReg(MSA311_REG_FREE_FALL_THRESHOLD,threshole);
	if (bRet == false)
	{
		perror("Msa311_SetFreeFallThreshole write error\n");
		return false;
	}

    return true;
}

static bool Msa311_SetFreeFallHy(uint8_t hy_value)
{
    bool bRet;
    bRet = Msa311_WirteReg(MSA311_REG_FREE_FALL_HY,hy_value);
	if (bRet == false)
	{
		perror("Msa311_SetFreeFallHy write error\n");
		return false;
	}

    return true;
}

bool Msa311_GetXYZData()
{
    msa311_range_t range;
    uint8_t r_data[6];
    bool bRet;
    float scale = 0.0;
    int16_t x, ///< The last read X acceleration in raw units
      y,     ///< The last read Y acceleration in raw units
      z;     ///< The last read Z acceleration in raw units
    float x_g, ///< The last read X acceleration in 'g'
      y_g,   ///< The last read Y acceleration in 'g'
      z_g;   ///< The last read X acceleration in 'g'

    bRet = Msa311_ReadRegs(MSA311_REG_OUT_X_L,r_data,sizeof(r_data));

    bRet |= Msa311_GetRange(&range);
    switch (range)
    {
    case MSA311_RANGE_2_G/* constant-expression */:
        /* code */
        scale = 1024;
        break;
    case MSA311_RANGE_4_G:
        scale = 512;
        break;
    case MSA311_RANGE_8_G:
        scale = 256;
        break;
    case MSA311_RANGE_16_G:
        scale = 128;
        break;        
    
    default:
        break;
    }

    x = r_data[0];
    x |= r_data[1] << 8;
    y = r_data[2];
    y |= r_data[3] << 8;
    z = r_data[4];
    z |= r_data[5] << 8;

    // 12 bits of data in 16 bit range
    x >>= 4;
    y >>= 4;
    z >>= 4;

    x_g = (float)x / scale ;
    y_g = (float)y / scale;
    z_g = (float)z / scale;

    if (bRet)
    {
#if DEBUG_X_Y_Y_DATA == 1        
        printf("get x = %0.2f g, y = %0.2f g, z = %0.2f g \r\n",x_g,y_g,z_g);
#endif        
    }
    else
    {
        perror("Msa311_GetXYZData error\r\n");
    }

    return true;
}

void Msa311_Init(void)
{
    uint8_t partID = 0;
    uint8_t reg;
    uint8_t threshold;
    msa311_powermode_t powerMode;
    msa311_axes_state_t state;
    msa311_dataRate_t dataRate;
    msa301_bandwidth_t bandWidth;
    msa311_range_t range;
    msa311_tapquite_t tapQuite;
    msa311_tapshock_t tapShock;
    msa311_tapduration_t tapDuration;
    msa311_bool_t enable;

    Msa311_GetPardId(&partID);

    if (partID == 0x13)
    {
        printf("Find Msa311 Device\r\n");
        printf("Now to Init Msa311\r\n");

        Msa311_SetPowerMode(MSA311_NORMALMODE);     // Power Mode == Normal Mode
        Msa311_GetPowerMode(&powerMode);
        printf("Msa311 Power Mode = 0x%02x\r\n",powerMode);

        Msa311_Set_Axes_Enable(AXES_ENABLE);        // 使能xyz轴
        Msa311_Get_Axes_Enable(&state); 
        printf("Msa311 Axes have %s\r\n",state == AXES_ENABLE ? "enable" : " disable ");

        Msa311_SetDataRate(MSA311_DATARATE_1000_HZ);
        Msa311_GetDataRate(&dataRate);
        printf("Msa311_GetDataRate == 0x%02x\r\n",dataRate);

        Msa311_SetBandWidth(MSA301_BANDWIDTH_500_HZ);
        Msa311_GetBandWidth(&bandWidth);
        printf("Msa311_GetBandWidth == 0x%02x\r\n",bandWidth);

        Msa311_SetRange(MSA311_RANGE_2_G);
        Msa311_GetRange(&range);
        printf("Msa311_GetRange == 0x%02x\r\n",range);


        Msa311_WirteReg(MSA311_REG_INTMAP0,0x00); //清除中断映射。
        Msa311_WirteReg(MSA311_REG_INTSET0,0x00); //关所有中断
    #if ENABLE_TAP_DETECT == 1
        Msa311_SetTapQuiteParam(MSA311_TAPQUITE_30_MS);
        Msa311_GetTapQuiteParam(&tapQuite);
        printf("Msa311_getTapQuiteParam == %s\r\n",tapQuite == MSA311_TAPQUITE_30_MS ? "MSA311_TAPQUITE_30_MS" : "MSA311_TAPQUITE_20_MS");

        Msa311_SetTapShockParam(MSA311_TAPSHOCK_50_MS);
        Msa311_GetTapShockParam(&tapShock);
        printf("Msa311_GetTapShockParam == %s\r\n",tapShock == MSA311_TAPSHOCK_50_MS ? "MSA311_TAPSHOCK_50_MS" : "MSA311_TAPSHOCK_70_MS");

        Msa311_SetTapDurationParam(MSA311_TAPDUR_250_MS);
        Msa311_GetTapDurationParam(&tapDuration);
        printf("Msa311_GetTapDurationParam == 0x%02x\r\n",tapDuration);

        Msa311_ThresholdConvertToRegister(1.0f,&reg);
        Msa311_SetTapThresholdParam(reg);
        Msa311_GetTapThresholdParam(&threshold);
        printf("Msa311_GetTapThresholdParam  == 0x%02x\r\n",threshold);

        //使能S_TAP D_TAP Int
        Msa311_SetInterruptMap0(MSA311_INTERRUPT_D_TAP,MSA311_BOOL_TRUE);
        Msa311_SetInterruptMap0(MSA311_INTERRUPT_S_TAP,MSA311_BOOL_TRUE);
        Msa311_GetInterruptMap0(MSA311_INTERRUPT_D_TAP,&enable);
        printf("Msa311_GetInterruptMap0 MSA311_INTERRUPT_D_TAP %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
        Msa311_GetInterruptMap0(MSA311_INTERRUPT_S_TAP,&enable);
        printf("Msa311_GetInterruptMap0 MSA311_INTERRUPT_S_TAP %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");

        Msa311_SetInterrupt0Enable(MSA311_INTERRUPT_D_TAP_EN,MSA311_BOOL_TRUE);
        Msa311_GetInterrupt0Enable(MSA311_INTERRUPT_D_TAP_EN,&enable);
        printf("Msa311_GetInterrupt0Enable MSA311_INTERRUPT_D_TAP %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
        
        Msa311_SetInterrupt0Enable(MSA311_INTERRUPT_S_TAP_EN,MSA311_BOOL_TRUE);
        Msa311_GetInterrupt0Enable(MSA311_INTERRUPT_S_TAP_EN,&enable);
        printf("Msa311_GetInterrupt0Enable MSA311_INTERRUPT_S_TAP_EN %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
   
    #endif

    #if ENABLE_ACTIVITE_DETECT == 1

        Msa311_SetActiveDurationParam(MSA311_ACTIVE_DURATION_1);
        Msa311_ActiveThresholdConvertToRegister(0.1f,&reg);
        Msa311_SetActiveThresholdParam(reg);

    // 映射活动中断
        Msa311_SetInterruptMap0(MSA311_INTERRUPT_ACTIVE,MSA311_BOOL_TRUE);
        Msa311_GetInterruptMap0(MSA311_INTERRUPT_ACTIVE,&enable);
        printf("Msa311_GetInterruptMap0 MSA311_INTERRUPT_ACTIVE %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
    
        Msa311_SetInterrupt0Enable(MSA311_INTERRUPT_ACTIVE_EN_X,MSA311_BOOL_TRUE);
        Msa311_GetInterrupt0Enable(MSA311_INTERRUPT_ACTIVE_EN_X,&enable);
        printf("Msa311_GetInterrupt0Enable MSA311_INTERRUPT_ACTIVE_EN_X %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
 
        Msa311_SetInterrupt0Enable(MSA311_INTERRUPT_ACTIVE_EN_Y,MSA311_BOOL_TRUE);
        Msa311_GetInterrupt0Enable(MSA311_INTERRUPT_ACTIVE_EN_Y,&enable);
        printf("Msa311_GetInterrupt0Enable MSA311_INTERRUPT_ACTIVE_EN_Y %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");

        Msa311_SetInterrupt0Enable(MSA311_INTERRUPT_ACTIVE_EN_Z,MSA311_BOOL_TRUE);
        Msa311_GetInterrupt0Enable(MSA311_INTERRUPT_ACTIVE_EN_Z,&enable);
        printf("Msa311_GetInterrupt0Enable MSA311_INTERRUPT_ACTIVE_EN_Z %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
    #endif

    #if ENABLE_ORIENT_DETECT == 1
        Msa311_SetInterruptMap0(MSA311_INTERRUPT_ORIENT,MSA311_BOOL_TRUE);
        Msa311_GetInterruptMap0(MSA311_INTERRUPT_ORIENT,&enable);
        printf("Msa311_GetInterruptMap0 MSA311_INTERRUPT_ORIENT %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");
        
        Msa311_SetInterrupt0Enable(MSA311_INTERRUPT_ORIENT_EN,MSA311_BOOL_TRUE);
        Msa311_GetInterrupt0Enable(MSA311_INTERRUPT_ORIENT_EN,&enable);
        printf("Msa311_GetInterrupt0Enable MSA311_INTERRUPT_ORIENT_EN %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");

    #endif

    #if ENABLE_FREE_FALL_DETECT == 1
        Msa311_SetFreeFallDuration(0x0A);
        Msa311_SetFreeFallThreshole(0x30);
        Msa311_SetFreeFallHy(0x01);

        Msa311_SetInterruptMap0(MSA311_INTERRUPT_FREE_FALL,MSA311_BOOL_TRUE);
        Msa311_GetInterruptMap0(MSA311_INTERRUPT_FREE_FALL,&enable);
        printf("Msa311_GetInterruptMap0 MSA311_INTERRUPT_ORIENT %s\r\n",enable==MSA311_BOOL_TRUE ? "enable" : "disable");

        Msa311_SetInterrupt1Enable(MSA311_INTERRUPT_FREE_FALLEN,MSA311_BOOL_TRUE); // 使能中断
    #endif

        printf("Msa311 Init Success!\r\n");

    }
    else
    {
        printf("ERROR: not Find Msa311 \r\n");
    }


    // while (1)
    // {
    //     Msa311_GetXYZData();
    //     BOARD_Delay1Ms(1000);
    // }  
}

void handle_int_message(void)
{
    uint8_t state;
    uint8_t orient_state;
    bool bRet;
    bRet = Msa311_ReadReg(MSA311_REG_MOTIONINT,&state);
    bRet = Msa311_ReadReg(MSA311_REG_ORIENTATION_STATUS,&orient_state);

	if (bRet == false)
	{
		perror("Msa311_GetInterrupt1Enable read error\n");
		return;
    }

    if (state & (1 << MSA311_S_TAP_INT_STATE))
    {
        printf("this is s_tap \r\n");
    }
    else if (state & (1 << MSA311_D_TAP_INT_STATE))
    {
        printf("this is d_tap \r\n");
    }
    else if (state & (1<< MSA311_ACTIVE_INT_STATE))
    {
        printf("this is active\r\n");
    }
    else if (state & (1 << MSA311_FREE_FALL_INT_STATE))
    {
        printf("this is free fall\r\n");
    }
#if ENABLE_ORIENT_DETECT == 1
    if (orient_state & 1<< 6)
    {
        printf("downward looking ");

        if ((orient_state & 0x30)>>4 == 0)
        {
            printf(" portrait upright \r\n");   
        }
        else if ((orient_state & 0x30)>>4 == 1)
        {
            printf(" portrait upside down \r\n");   
        }
        else if ((orient_state & 0x30 ) >> 4 == 2)
        {
            printf(" landscape left \r\n") ;  
        }
        else if ((orient_state & 0x30 ) >> 4 == 3)
        {
            printf(" landscape right \r\n");   
        }
    }
    else
    {
        printf("  upward looking  ");
        if ((orient_state & 0x30 ) >> 4 == 0)
        {
            printf(" portrait upright \r\n");   
        }
        else if ((orient_state & 0x30)>>4 == 1)
        {
            printf(" portrait upside down \r\n");   
        }
        else if ((orient_state & 0x30 ) >> 4 == 2)
        {
            printf(" landscape left \r\n") ;  
        }
        else if ((orient_state & 0x30 ) >> 4 == 3)
        {
            printf(" landscape right \r\n");   
        }
    }
#endif    
}